package com.cqie.service.impl;

import com.cqie.dto.user.DoctorLoginDto;
import com.cqie.entity.DoctorLogin;
import com.cqie.exception.SpecialException;
import com.cqie.mapper.user.DoctorsLoginMapper;
import com.cqie.service.IDoctorsLoginService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqie.util.JwtTokenUtil;
import com.cqie.util.Md5Util;
import com.cqie.util.RedisUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 不吃海鲜
 * @since 2024-11-25
 */
@Service
@Slf4j
public class DoctorLoginServiceImpl extends ServiceImpl<DoctorsLoginMapper, DoctorLogin> implements IDoctorsLoginService {


    @Resource
    private  DoctorsLoginMapper doctorsLoginMapper;

    private final RedisUtils redisUtils;

    public DoctorLoginServiceImpl(RedisUtils redisUtils) {
        this.redisUtils = redisUtils;
    }


    /**
     * 注册医生
     * @param doctorLoginDto
     * @return
     */
    @Override
    public Boolean registerDoctor(DoctorLoginDto doctorLoginDto) throws SpecialException {
        // 查询数据库已有的全部数据
        var doctorsLoginList = doctorsLoginMapper.getDoctorsLoginList();
        // 判断数据库中是否已存在该账号和电话号码
         var data = doctorsLoginList.stream()
                .anyMatch(s -> s.getDoctorAccount().equals(doctorLoginDto.getDoctorAccount())
                        || s.getDoctorPhone().equals(doctorLoginDto.getDoctorPhone()));
        // 如果存在则抛出异常
        if (data && doctorsLoginList.size() > 0) {
            throw new SpecialException("该账号或者电话已存在");
        }

        // 将密码加密然后放到实体类中
        try {

            DoctorLogin doctorLogin = DoctorLogin.builder()
                    .doctorAccount(doctorLoginDto.getDoctorAccount())
                    .doctorPassword(Md5Util.md5(doctorLoginDto.getDoctorPassword()))
                    .doctorPhone(doctorLoginDto.getDoctorPhone())
                    .build();

            // 将实体类存入数据库
            doctorsLoginMapper.insert(doctorLogin);
            return true;

        } catch (Exception e) {
            log.error("密码加密失败" , e);
            throw new SpecialException("密码加密失败");
        }

    }



    /**
     * 医生登陆
     * @param doctorLoginDto
     * @return
     */
    @Override
    public String doctorLogin(DoctorLoginDto doctorLoginDto) {

        try {
            var doctorsLoginEntity = doctorsLoginMapper.selectByAccount(doctorLoginDto.getDoctorAccount());
            var checkPassWord = Md5Util.passwordVerify(doctorLoginDto.getDoctorPassword(), doctorsLoginEntity.getDoctorPassword());

            log.info("密码校验结果: " + checkPassWord);

            if (checkPassWord && !ObjectUtils.isEmpty(doctorsLoginEntity)) {
                //生成一个安全的令牌，用于在客户端和服务器之间进行身份验证和授权
                var token = JwtTokenUtil.buildJwt(doctorsLoginEntity.getDoctorId(),
                        doctorsLoginEntity.getDoctorAccount());

                if (!StringUtils.hasText(token)){
                   throw new SpecialException("token生成失败");
                }
                token = "doctor:" + token ;
                log.info("用户登录成功，生成token为：" + token);

                // k : token v: DoctorsLoginEntity 过期时间: 15min 单位: 毫秒
                var saveTokenToRedis = redisUtils.set(token , doctorsLoginEntity , JwtTokenUtil.KEEP_TIME ,
                        TimeUnit.MILLISECONDS);
                log.info("token存入redis结果: " + saveTokenToRedis);
                if (!saveTokenToRedis){
                    throw new SpecialException("token存入redis失败");
                }

                return token;
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return null;
    }

    /**
     * 医生登出
     * @param doctorToken
     * @return
     */
    @Override
    public Boolean doctorLogout(String doctorToken) throws SpecialException {

        // 校验token是否为空
        if (ObjectUtils.isEmpty(doctorToken)){
            throw new SpecialException("token不能为空");
        }

        // 删除redis中的token
        redisUtils.del(doctorToken);

        // 查询一般
        var result = redisUtils.get(doctorToken);

        if (!ObjectUtils.isEmpty(result)){
            throw new SpecialException("退出异常");
        }

        return true;
    }
}
